from typing import Union, List
import abc

from src.LogPlayer.utils.CustomParser import CustomParser
from src.LogPlayer.entity.LogLine import LogLine
from src.LogPlayer.constants.constants import *

class DataSource(metaclass=abc.ABCMeta):
    _startTime: int = -1
    _endTime: int = -1
    _duration: int = -1
    _parser = CustomParser()

    @abc.abstractmethod
    def prepare(self) -> int:
        pass

    def getStartTime(self) -> int:
        return self._startTime

    def getEndTime(self) -> int:
        """
        获取log文件结束时间戳.
        :returns: 结束时间(时间戳)
        """
        return self._endTime

    def getDuration(self) -> int:
        return self._duration

    @abc.abstractmethod
    def seekTo(self, timeMills):
        pass

    @abc.abstractmethod
    def readNext(self) -> LogLine:
        pass

    def release(self):
        pass


class FileDataSource(DataSource):
    paths: str | List[str]
    packets: List[LogLine] = []
    anchorPackets: List[LogLine] = []

    def __init__(self, paths: str | List[str]):
        if not isinstance(paths, str):
            raise ValueError("not support paths in List.")
        self.paths = paths

    def prepare(self) -> int:
        # fo = open(self.paths, "r", encoding='utf-8')
        fo = open(self.paths, "r", encoding='ISO-8859-1')
        fileId = 0  # TODO 多文件
        lineNo = 0
        line = fo.readline()
        while line:
            lineInfo = self._parse(line)
            lineInfo._fileId = fileId
            lineInfo._lineNo = lineNo
            lineNo += 1
            if lineInfo._flags != 0:
                self.packets.append(lineInfo)
                if lineInfo._flags & LOG_FLAG_SCREEN_BEGIN == LOG_FLAG_SCREEN_BEGIN:
                    self.anchorPackets.append(lineInfo)
            line = fo.readline()
        print('prepare success, len(packets) = ' + str(len(self.packets)))
        fo.close()
        if len(self.packets) > 0:
            self.startTime = self.packets[0].timeStamp
            self.endTime = self.packets[-1].timeStamp
            self.duration = self.endTime - self.startTime
        else:
            self.startTime = self.endTime = self.duration = -1

        print('prepare completed')
        return 0

    def resume(self):
        pass

    def pause(self):
        pass

    def seekTo(self, timeMills):
        raise ValueError("not support seekTo.")

    def readNext(self) -> LogLine:
        pass

    def release(self):
        if self.packets:
            del self.packets

    def _parse(self, line: str) -> LogLine:
        return self._parser.parseSourceLine(line)

    def _getIndexBE(self, packets: List[LogLine], timestamp: int, type: int):
        pass


class StreamDataSource(DataSource):
    pass
